package com.zbkj.crmeb.store.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crmeb.core.exception.CrmebException;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.category.request.CategoryRequest;
import com.zbkj.crmeb.category.vo.CategoryTreeVo;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.crmeb.store.dao.ChannelCategoryConfigDao;
import com.zbkj.crmeb.store.model.ChannelCategoryConfig;
import com.zbkj.crmeb.store.service.ChannelCategoryConfigService;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ChannelCategoryConfigServiceImpl extends ServiceImpl<ChannelCategoryConfigDao, ChannelCategoryConfig> implements ChannelCategoryConfigService {

    @Autowired
    private ChannelCategoryConfigDao channelCategoryConfigDao;
    @Autowired
    private ICategoryMatchService categoryMatchService;

    /**
     * 商户后台修改url和启用状态
     * @param categoryRequest
     * @param merId
     * @return java.lang.Boolean
     */
    @Override
    public Boolean updChannelCategory(CategoryRequest categoryRequest,Integer merId) {
        CategoryMatch categoryMatch = categoryMatchService.getById(categoryRequest.getId());
        if (Objects.isNull(categoryMatch)){
            throw new CrmebException("分类id异常");
        }
        if (!categoryMatch.getStatus() && categoryRequest.getStatus()){
            throw new CrmebException("总后台未启用,不允许开启");
        }
        ChannelCategoryConfig channelCategoryConfig = this.getOne(new LambdaQueryWrapper<>(ChannelCategoryConfig.class)
                .eq(ChannelCategoryConfig::getCateId,categoryMatch.getId())
                .eq(ChannelCategoryConfig::getMerId,merId));
        //判断商户分类是否存在，不存在就新增
        if (Objects.isNull(channelCategoryConfig)){
            channelCategoryConfig = new ChannelCategoryConfig();
            channelCategoryConfig.setMerId(merId);
            channelCategoryConfig.setCateId(categoryMatch.getId());
            channelCategoryConfig.setCreateTime(new Date());
            this.save(channelCategoryConfig);
        }
        channelCategoryConfig.setExtra(categoryRequest.getExtra());
        channelCategoryConfig.setStatus(categoryRequest.getStatus());
        channelCategoryConfig.setUpdateTime(new Date());
        //商户后台禁用/启用分类
        if (!channelCategoryConfig.getStatus()){
            //查询商户所有启用的分类
            List<CategoryMatch> enableCategoryMatch = categoryMatchService.getCategoryMatch(merId);
            //获取三级用户
            enableCategoryMatch = enableCategoryMatch.stream().filter(categoryMatch1 -> categoryMatch1.getPath().length() - categoryMatch1.getPath().replace("/","").length() == 4).collect(Collectors.toList());
            //查询需要禁用的分类(下一级分类)
            List<CategoryMatch> categoryMatchList = categoryMatchService.list(new LambdaQueryWrapper<>(CategoryMatch.class).like(CategoryMatch::getPath,"/" + channelCategoryConfig.getCateId() + "/"));
            List<Integer> integerList = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
            //查看是否存在不需要禁用的分类,至少有一个启用的分类要满足不在禁用分类中
            enableCategoryMatch = enableCategoryMatch.stream().filter(categoryMatch1 -> !Objects.equals(categoryMatch1.getId(),categoryMatch.getId())).collect(Collectors.toList());
            if (enableCategoryMatch.stream().allMatch(categoryMatch1 -> integerList.contains(categoryMatch1.getId()))){
                throw new CrmebException("启用状态需至少保留一个");
            }
            if (!CollectionUtils.isEmpty(categoryMatchList)){
                //查询商户分类表中需要禁用的分类
                List<ChannelCategoryConfig> disabledCategoryList = channelCategoryConfigDao.selectList(new LambdaQueryWrapper<>(ChannelCategoryConfig.class)
                        .eq(ChannelCategoryConfig::getMerId,merId).in(ChannelCategoryConfig::getCateId,integerList));
                List<Integer> disabledIntList = disabledCategoryList.stream().map(ChannelCategoryConfig::getCateId).collect(Collectors.toList());
                //如果商户分类表中没有对应的分类表示需要新增在禁用
                categoryMatchList.forEach(categoryMatch2 -> {
                    if (!disabledIntList.contains(categoryMatch2.getId())){
                        ChannelCategoryConfig config = new ChannelCategoryConfig();
                        config.setMerId(merId);
                        config.setCateId(categoryMatch2.getId());
                        config.setCreateTime(new Date());
                        disabledCategoryList.add(config);
                    }
                });
                disabledCategoryList.forEach(channelCategoryConfig1 -> channelCategoryConfig1.setStatus(false));
                this.saveOrUpdateBatch(disabledCategoryList);
            }
        }else {
            /*//分类启用时需要先启用下级
            List<CategoryMatch> categoryMatchList = categoryMatchService.list(new LambdaQueryWrapper<>(CategoryMatch.class).eq(CategoryMatch::getPid,channelCategoryConfig.getCateId()));
            if (!CollectionUtils.isEmpty(categoryMatchList)){
                List<Integer> integerList = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
                //查询当前商户分类下级是否有启用数据
                int integer = this.count(new LambdaQueryWrapper<>(ChannelCategoryConfig.class).eq(ChannelCategoryConfig::getMerId,merId).in(ChannelCategoryConfig::getCateId,integerList).eq(ChannelCategoryConfig::getStatus,true));
                if (integer == 0){
                    throw new CrmebException("请先开启下级分类");
                }
            }*/
            //分类开启后需要开启上一级分类
            List<Integer> categoryIdList = CrmebUtil.stringToArrayByRegex(categoryMatch.getPath(), "/");
            categoryIdList.removeIf(i -> i.equals(0));
            if(categoryIdList.size() >= 1){
                ChannelCategoryConfig config = new ChannelCategoryConfig();
                config.setStatus(channelCategoryConfig.getStatus());
                config.setUpdateTime(new Date());
                update(config,new LambdaQueryWrapper<>(ChannelCategoryConfig.class).eq(ChannelCategoryConfig::getMerId,merId).in(ChannelCategoryConfig::getCateId,categoryIdList));
            }
            //分类开启后，开启下一级所有分类
            openAllSubCategory(categoryRequest.getId(), merId, false);
        }
        return this.updateById(channelCategoryConfig);
    }

    /**
     * 总后台关闭分类状态时，商户后台也需要关闭对应的分类状态
     * @param cateId
     * @return java.lang.Boolean
     */
    @Override
    public Boolean closeStatusByCateId(Integer cateId) {
        //查询是否有下级
        List<CategoryMatch> categoryMatchList = categoryMatchService.list(new LambdaQueryWrapper<>(CategoryMatch.class).like(CategoryMatch::getPath,"/" + cateId + "/"));
        List<Integer> integerList = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
        integerList.add(cateId);
        ChannelCategoryConfig config = new ChannelCategoryConfig();
        config.setStatus(false);
        config.setUpdateTime(new Date());
        return update(config,new LambdaQueryWrapper<>(ChannelCategoryConfig.class).in(ChannelCategoryConfig::getCateId,integerList));
    }

    /**
     * 小程序 - 带结构的无线级分类
     * @author Mr.Zhang
     * @since 2020-04-16
     */
    @Override
    public List<CategoryTreeVo> getFrontTreeByMerId(Integer merId) {

        List<CategoryMatch> categoryMatchList = categoryMatchService.getCategoryMatch(merId);
        if(CollectionUtils.isEmpty(categoryMatchList)){
            return null;
        }
        List<CategoryTreeVo> treeList = new ArrayList<>();
        List<CategoryTreeVo> finalTreeList = treeList;
        categoryMatchList.stream().forEach(e->{
            CategoryTreeVo categoryTreeVo = new CategoryTreeVo();
            BeanUtils.copyProperties(e, categoryTreeVo);
            finalTreeList.add(categoryTreeVo);
        });
        //返回
        Map<Integer, CategoryTreeVo> map = new HashMap<>();
        //ID 为 key 存储到map 中
        for (CategoryTreeVo categoryTreeVo1 : treeList) {
            map.put(categoryTreeVo1.getId(), categoryTreeVo1);
        }
        treeList = treeList.stream().sorted(Comparator.comparing(CategoryTreeVo::getSort,Comparator.reverseOrder())).collect(Collectors.toList());
        List<CategoryTreeVo> list = new ArrayList<>();
        for (CategoryTreeVo tree : treeList) {
            //子集ID返回对象，有则添加。
            CategoryTreeVo tree1 = map.get(tree.getPid());
            if(tree1 != null){
                tree1.getChild().add(tree);
            }else {
                tree.setCids(tree.getId().toString());
                list.add(tree);
            }
        }
        //全部
        for (CategoryTreeVo tree : list) {
            //子集大于0，有则添加。
            List<CategoryTreeVo> childList = tree.getChild();
            StringBuilder allBuilder = new StringBuilder();
            if (!CollectionUtils.isEmpty(childList)) {
                for (CategoryTreeVo child : childList){
                    if (null != child.getId()) {
                        //全部
                        allBuilder.append(child.getId()).append(",");
                        //子类
                        child.setCids(child.getId().toString());
                        if(!CollectionUtils.isEmpty(child.getChild())){
                            child.getChild().forEach(e->e.setCids(e.getId().toString()));
                        }
                    }
                }
                CategoryTreeVo all = new CategoryTreeVo();
                all.setCids(allBuilder.deleteCharAt(allBuilder.length() - 1).toString());
                all.setPid(tree.getPid());
                all.setType(1);
                all.setSort(1);
                all.setPath(tree.getPath() + tree.getId());
                all.setStatus(true);
                all.setName("全部" + tree.getName());
                //重新排序
                List<CategoryTreeVo> newChild = new ArrayList<>();
                newChild.add(all);
                newChild.addAll(childList);
                tree.setChild(newChild);
            }
        }
        list.forEach(categoryTreeVo -> {
            List<CategoryTreeVo> child = categoryTreeVo.getChild();
            categoryTreeVo.setChild(child.stream().filter(categoryTreeVo1 -> !CollectionUtils.isEmpty(categoryTreeVo1.getChild())).collect(Collectors.toList()));
        });
        return list.stream().filter(categoryTreeVo1 -> !CollectionUtils.isEmpty(categoryTreeVo1.getChild())).collect(Collectors.toList());
    }

    /**
     * 修改渠道商户分类删除标志
     * @param categoryRequest
     * @return java.lang.Boolean
     */
    @Override
    public Boolean updCategoryEnableFlag(CategoryRequest categoryRequest) {

        CategoryMatch categoryMatch = categoryMatchService.getById(categoryRequest.getId());
        if (Objects.isNull(categoryMatch)){
            throw new CrmebException("分类id异常");
        }
        if (!categoryMatch.getStatus()){
            throw new CrmebException("总后台未启用");
        }
        ChannelCategoryConfig channelCategoryConfig = this.getOne(new LambdaQueryWrapper<>(ChannelCategoryConfig.class)
                .eq(ChannelCategoryConfig::getCateId,categoryMatch.getId())
                .eq(ChannelCategoryConfig::getMerId,categoryRequest.getMerId()));
        //判断商户分类是否存在，不存在就新增
        if (Objects.isNull(channelCategoryConfig)){
            channelCategoryConfig = new ChannelCategoryConfig();
            channelCategoryConfig.setMerId(categoryRequest.getMerId());
            channelCategoryConfig.setCateId(categoryMatch.getId());
            channelCategoryConfig.setCreateTime(new Date());
            this.save(channelCategoryConfig);
        }
        channelCategoryConfig.setStatus(categoryMatch.getStatus());
        channelCategoryConfig.setEnableFlag(categoryRequest.getEnableFlag());
        channelCategoryConfig.setUpdateTime(new Date());
        //商户后台禁用/启用分类
        if (!channelCategoryConfig.getEnableFlag()){
            //查询商户所有的分类
            List<CategoryMatch> enableCategoryMatch = channelCategoryConfigDao.getCategoryByEnableFlag(categoryRequest.getMerId());
            //获取三级用户
            enableCategoryMatch = enableCategoryMatch.stream().filter(categoryMatch1 -> categoryMatch1.getPath().length() - categoryMatch1.getPath().replace("/","").length() == 4).collect(Collectors.toList());
            //查询需要禁用的分类(下一级分类)
            List<CategoryMatch> categoryMatchList = categoryMatchService.list(new LambdaQueryWrapper<>(CategoryMatch.class).like(CategoryMatch::getPath,"/" + channelCategoryConfig.getCateId() + "/"));
            List<Integer> integerList = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
            //查看是否存在不需要禁用的分类,至少有一个启用的分类要满足不在禁用分类中
            enableCategoryMatch = enableCategoryMatch.stream().filter(categoryMatch1 -> !Objects.equals(categoryMatch1.getId(),categoryMatch.getId())).collect(Collectors.toList());
            if (enableCategoryMatch.stream().allMatch(categoryMatch1 -> integerList.contains(categoryMatch1.getId()))){
                throw new CrmebException("启用状态需至少保留一个");
            }
            if (!CollectionUtils.isEmpty(categoryMatchList)){
                //查询商户分类表中需要禁用的分类
                List<ChannelCategoryConfig> disabledCategoryList = channelCategoryConfigDao.selectList(new LambdaQueryWrapper<>(ChannelCategoryConfig.class)
                        .eq(ChannelCategoryConfig::getMerId,categoryRequest.getMerId()).in(ChannelCategoryConfig::getCateId,integerList));
                List<Integer> disabledIntList = disabledCategoryList.stream().map(ChannelCategoryConfig::getCateId).collect(Collectors.toList());
                //如果商户分类表中没有对应的分类表示需要新增在禁用
                categoryMatchList.forEach(categoryMatch2 -> {
                    if (!disabledIntList.contains(categoryMatch2.getId())){
                        ChannelCategoryConfig config = new ChannelCategoryConfig();
                        config.setMerId(categoryRequest.getMerId());
                        config.setCateId(categoryMatch2.getId());
                        config.setCreateTime(new Date());
                        config.setStatus(categoryMatch.getStatus());
                        disabledCategoryList.add(config);
                    }
                });
                disabledCategoryList.forEach(channelCategoryConfig1 -> channelCategoryConfig1.setEnableFlag(false));
                this.saveOrUpdateBatch(disabledCategoryList);
            }
        }else {
            /*//分类启用时需要先启用下级
            List<CategoryMatch> categoryMatchList = categoryMatchService.list(new LambdaQueryWrapper<>(CategoryMatch.class).eq(CategoryMatch::getPid,channelCategoryConfig.getCateId()));
            if (!CollectionUtils.isEmpty(categoryMatchList)){
                List<Integer> integerList = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
                //查询当前商户分类下级是否有启用数据
                int integer = this.count(new LambdaQueryWrapper<>(ChannelCategoryConfig.class).eq(ChannelCategoryConfig::getMerId,merId).in(ChannelCategoryConfig::getCateId,integerList).eq(ChannelCategoryConfig::getStatus,true));
                if (integer == 0){
                    throw new CrmebException("请先开启下级分类");
                }
            }*/
            //分类开启后需要开启上一级分类
            List<Integer> categoryIdList = CrmebUtil.stringToArrayByRegex(categoryMatch.getPath(), "/");
            categoryIdList.removeIf(i -> i.equals(0));
            if(categoryIdList.size() >= 1){
                ChannelCategoryConfig config = new ChannelCategoryConfig();
                config.setEnableFlag(channelCategoryConfig.getEnableFlag());
                config.setUpdateTime(new Date());
                update(config,new LambdaQueryWrapper<>(ChannelCategoryConfig.class).eq(ChannelCategoryConfig::getMerId,categoryRequest.getMerId()).in(ChannelCategoryConfig::getCateId,categoryIdList));
            }
            //分类开启后，开启下一级所有分类
            openAllSubCategory(categoryRequest.getId(), categoryRequest.getMerId(), true);

        }
        return this.updateById(channelCategoryConfig);
    }

    /**
     * 获取商户后台分类树结构
     * @param merId
     * @return java.util.List<com.zbkj.crmeb.category.vo.CategoryTreeVo>
     */
    @Override
    public List<CategoryTreeVo> getCategoryTree(Integer merId) {
        //查询商户所有的分类
        List<CategoryMatch> enableCategoryMatch = channelCategoryConfigDao.getCategoryByEnableFlag(merId);
        if (CollectionUtils.isEmpty(enableCategoryMatch)){
            return null;
        }
        //循环数据，把数据对象变成带list结构的vo
        List<CategoryTreeVo> treeList = new ArrayList<>();
        enableCategoryMatch.forEach(categoryMatch -> {
            CategoryTreeVo categoryTreeVo = Convert.convert(CategoryTreeVo.class,categoryMatch);
            categoryTreeVo.setType(categoryMatch.getType().getCode());
            treeList.add(categoryTreeVo);
        });
        //返回
        Map<Integer, CategoryTreeVo> map = treeList.stream().collect(Collectors.toMap(CategoryTreeVo::getId,categoryTreeVo -> categoryTreeVo));
        List<CategoryTreeVo> list = new ArrayList<>();
        for (CategoryTreeVo tree : treeList) {
            //子集ID返回对象，有则添加。
            CategoryTreeVo tree1 = map.get(tree.getPid());
            if(tree1 != null){
                tree1.getChild().add(tree);
            }else {
                list.add(tree);
            }
        }
        return list;
    }

    /**
     * 功能描述: 启用分类时，打开所有子分类
     * @Param: [cateId]
     * @Return: void
     * @Author: wangzh
     * @Date: 2022/12/21 14:49
     */
    private void openAllSubCategory(Integer cateId, Integer merId, Boolean flag){
        //所有子分类集合
        List<CategoryMatch> categoryMatchList = categoryMatchService.list(Wrappers.<CategoryMatch>lambdaQuery().eq(CategoryMatch::getPid, cateId));
        if (CollectionUtils.isEmpty(categoryMatchList)){
            return;
        }
        categoryMatchList.forEach(e -> openAllSubCategory(e.getId(), merId, flag));
        //待开启的分类id
        List<Integer> enableIds = categoryMatchList.stream().map(CategoryMatch::getId).collect(Collectors.toList());
        //商户配置中已有的分类，没有的进行创建
        List<ChannelCategoryConfig> enableList = channelCategoryConfigDao.selectList(Wrappers.<ChannelCategoryConfig>lambdaQuery().eq(ChannelCategoryConfig::getMerId, merId).in(ChannelCategoryConfig::getCateId, enableIds));
        //遍历商家以创建过的分类，从待开启集合中移除
        enableList.forEach(e -> enableIds.remove(e.getCateId()));
        Map<Integer, Boolean> map = categoryMatchList.stream().collect(Collectors.toMap(CategoryMatch::getId, CategoryMatch::getStatus));
        //剩余商家没有的，进行创建，添加入集合
        if (!CollectionUtils.isEmpty(enableIds)){
            for (Integer id : enableIds){
                ChannelCategoryConfig config = new ChannelCategoryConfig();
                config.setCateId(id).setMerId(merId).setCreateTime(new Date()).setStatus(map.get(id)).setEnableFlag(true).setUpdateTime(new Date());
                enableList.add(config);
            }
        }
        //所有分类设置为开启
        // enableFlag为总后台设置， status为商户后台
        if (flag) {
            enableList.forEach(e -> e.setEnableFlag(true));
        } else {
            enableList.forEach(e -> e.setStatus(true));
        }
        saveOrUpdateBatch(enableList);
    }

}
